package com.dongrj.framework.core.model;

import com.dongrj.framework.core.utils.CollectionUtils;
import com.dongrj.framework.core.utils.StringUtils;
import lombok.Data;

import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dongrongjun
 * @date 2020/08/04
 */
@Data
public abstract class BaseExample {

    /**
     * 当前页
     */
    private int currentPage;
    /**
     * 分页大小
     */
    private int pageSize;
    /**
     * 分页起始位置
     */
    private Integer start;
    /**
     * 查询返回列
     */
    private List<String> columns;
    /**
     * 分组列
     */
    private List<String> groups;

    /**
     * 分组条件
     */
    private String having;

    /**
     * 计算分页起始位置
     */
    public void configStart() {
        if (currentPage == 0 || pageSize == 0) {
            return;
        }
        int result = Math.max(currentPage - 1, 0);
        this.start = result * pageSize;
    }


    public abstract List<String> getColumnList();

    public void setIncludeColumns(String... columns) {
        if (Objects.nonNull(columns)) {
            List<String> collect = Arrays.stream(columns).filter(this::isNotEmpty).collect(Collectors.toList());
            setColumns(collect);
        }
    }

    public void setOrderByClause(String orderByClause) {

    }

    public String getOrderByClause() {
        return null;
    }


    public void page(AbstractPage abstractPage) {
        page(abstractPage.getCurrentPage(), abstractPage.getPageSize());
    }


    public void page(int currentPage, int pageSize) {
        this.currentPage = currentPage;
        this.pageSize = pageSize;
    }

    private boolean equalsDate(String field) {
        if (StringUtils.equals(ModelConst.CREATE_DATE, field)) {
            return true;
        }
        return StringUtils.equals(ModelConst.EDIT_DATE, field);
    }


    private boolean equalsId(String field) {
        return StringUtils.equals(ModelConst.ID, field);
    }


    private boolean equalsIdAndDate(String field) {
        if (StringUtils.equals(ModelConst.CREATE_DATE, field)) {
            return true;
        }
        if (StringUtils.equals(ModelConst.EDIT_DATE, field)) {
            return true;
        }
        return StringUtils.equals(ModelConst.ID, field);
    }

    public void setExcludeColumns(String... excludeCols) {
        List<String> columnList = getColumnList();
        CollectionUtils.remove(columnList, excludeCols);
        setColumns(columnList);
    }

    public void excludeDateColumn() {
        excludeDateColumn(new String[]{});
    }

    public void excludeDateColumn(String... excludeCols) {
        List<String> columnList = getColumnList();
        List<String> collect = columnList.stream().filter(item -> !equalsDate(item)).collect(Collectors.toList());
        CollectionUtils.remove(collect, excludeCols);
        setColumns(collect);
    }

    public void excludeIdColumn() {
        excludeIdColumn(new String[]{});
    }

    public void excludeIdColumn(String... excludeCols) {
        List<String> columnList = getColumnList();
        List<String> collect = columnList.stream().filter(item -> !equalsId(item)).collect(Collectors.toList());
        CollectionUtils.remove(collect, excludeCols);
        setColumns(collect);
    }


    public void excludeIdAndDateColumn() {
        excludeIdAndDateColumn(new String[]{});
    }

    public void excludeIdAndDateColumn(String... excludeCols) {
        List<String> columnList = getColumnList();
        List<String> collect = columnList.stream().filter(item -> !equalsIdAndDate(item)).collect(Collectors.toList());
        CollectionUtils.remove(collect, excludeCols);
        setColumns(collect);
    }

    public void setGroups(String... groups) {
        if (Objects.nonNull(groups)) {
            List<String> collect = Arrays.stream(groups).collect(Collectors.toList());
            setGroups(collect);
        }
    }


    /**
     * 获取时候计算起始位置
     */
    public Integer getStart() {
        configStart();
        return start;
    }

    public List<String> getColumns() {
        return columns;
    }

    public void setColumns(List<String> columns) {
        this.columns = columns;
    }

    public List<String> getGroups() {
        return groups;
    }

    public void setGroups(List<String> groups) {
        this.groups = groups;
    }

    private boolean isNotEmpty(String string) {
        if (Objects.isNull(string)) {
            return false;
        }
        return string.length() > 0;
    }

    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof String) {
            return ((String) obj).length() == 0;
        }
        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }
        if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        }
        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }
        return false;
    }

}
